package com.schezhi.link.auth.session;

import com.c39.cloud.rbac.model.auth.AuthCommonVO;
import com.c39.cloud.rbac.model.auth.AuthStaffVO;
import com.cqfan.cloud.framework.jwt.component.JwtComponent;
import com.cqfan.cloud.framework.redis.client.RedisFacade;
import com.cqfan.cloud.framework.utils.BeanUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.schezhi.link.auth.model.UserAuthModel;
import com.schezhi.link.auth.properties.SessionProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;

/**
 * @author JiaLing.Fan
 * @version 1.0
 * @date 2023/3/14 23:52
 * @description RemoteSessionTemplate
 */


@Component
@Slf4j
public class RemoteSessionTemplate implements SessionTemplate<UserAuthModel>{

    private ThreadLocal<String> threadLocal = new ThreadLocal<String>();

    @Resource
    private SessionProperties sessionProperties;

    @Resource
    private JwtComponent jwtComponent;

    @Resource
    private ObjectMapper objectMapper;

    @Resource
    private RedisFacade redisFacade;


    @Override
    public UserAuthModel get() {
        String value = this.threadLocal.get();
        return get(value);
    }

    @Override
    public UserAuthModel get(String sessionId) {
     //   String signature = JWT.decode(sessionId).getSignature();
        String key =  jwtComponent.getAudience(sessionId);
        jwtComponent.verifyToken(sessionId, key);
        this.threadLocal.set(sessionId);
        if(redisFacade.get(sessionProperties.getPrefix() + key) == null){
            return  null;
        }else{
            try {
                return  objectMapper.readValue(redisFacade.get(sessionProperties.getPrefix() + key), UserAuthModel.class);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }
    }


    @Override
    public UserAuthModel getSign(String sessionId) {
        return get(sessionId);
    }

    @Override
    public void put(String sessionId, AuthStaffVO data) {
        String key =  jwtComponent.getAudience(sessionId);
        try {
          String dataStr =   objectMapper.writeValueAsString(data);
            redisFacade.set(sessionProperties.getPrefix() + key, dataStr);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void putSign(String sessionId, UserAuthModel data) {
        try {
        String key =  jwtComponent.getAudience(sessionId);
        data.setLastLoginTime(System.currentTimeMillis());
        data.setValidityTime(Long.valueOf(sessionProperties.getExpires() * 60 * 1000));
        String dataStr = objectMapper.writeValueAsString(data);
        redisFacade.set(sessionProperties.getPrefix() + key, dataStr , sessionProperties.getExpires());
        redisFacade.zset(sessionProperties.getPrefix() + "online",data.getLastLoginTime() * 1.0,  data.getStaffNumber());
        AuthCommonVO authCommonVO = new AuthCommonVO();
        BeanUtils.copyProperties(data,authCommonVO);
        authCommonVO.setLdap(authCommonVO.getStaffName());
        String value = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(authCommonVO);
        } catch (IOException e) {
            throw new RuntimeException("未知异常");
        }
    }

    @Override
    public void putSign(String sessionId, UserAuthModel data, int expires) {
        String key =  jwtComponent.getAudience(sessionId);
        String dataStr = null;
        try {
            dataStr = objectMapper.writeValueAsString(data);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        redisFacade.set(sessionProperties.getPrefix() + key, dataStr , expires);
    }

    @Override
    public void remove(String sessionId) {
        String key =  jwtComponent.getAudience(sessionId);
        redisFacade.del(sessionProperties.getPrefix() + key);
        //this.properties.remove(sessionId);
    }

    @Override
    public Map<String, UserAuthModel> gets() {
        //TODO 暂不支持从远程加载所有数据
        return null;
    }

    @Override
    public void removes() {
        //TODO 暂不支持清空所有数据
      //  this.properties.clear();
    }

    @Override
    public void currentThreadremove() {
        this.threadLocal.remove();
    }

}
